Hibernate-এ auditing বলতে বুঝানো হয়, ডেটাবেসে কোনো অবজেক্টের পরিবর্তন (যেমন তৈরি, আপডেট, মুছে ফেলা) ট্র্যাক করার প্রক্রিয়া। এই auditing কাজটি Hibernate Interceptors এবং Listeners ব্যবহার করে সহজেই করা যেতে পারে। এগুলি entity lifecycle events (যেমন, create, update, delete) ট্র্যাক করার জন্য ব্যবহৃত হয়, যাতে আপনি audit information (যেমন, last modified date, modified by, created by) সংগ্রহ করতে পারেন।
Hibernate Interceptors এবং Listeners এমন callback mechanisms যা entity এর lifecycle events (create, update, delete) এর সময় স্বয়ংক্রিয়ভাবে কার্যকর হয়। এই ক্যাপাবিলিটিজ ব্যবহার করে আপনি বিভিন্ন ধরণের auditing তথ্য ট্র্যাক করতে পারেন।
1. Hibernate Interceptors
Hibernate Interceptor হল একটি callback mechanism যা Hibernate এর মাধ্যমে entity lifecycle events (যেমন, save, update, delete) হ্যান্ডেল করে। Hibernate Interceptor ব্যবহার করে আপনি entity তে যে কোনো পরিবর্তন সঞ্চালনের সময় অতিরিক্ত কার্যকলাপ সম্পাদন করতে পারেন, যেমন auditing তথ্য (created/modified time, modified by user) যোগ করা।
Interceptor এর কাজ করার উপায়:
- preInsert: Entity যখন insert হয়, তখন এই মেথডটি কল হয়।
- preUpdate: Entity যখন update হয়, তখন এই মেথডটি কল হয়।
- preDelete: Entity যখন delete হয়, তখন এই মেথডটি কল হয়।
Interceptor Example:
import org.hibernate.EmptyInterceptor;
import org.hibernate.type.Type;
import java.io.Serializable;
import java.util.Date;
public class AuditInterceptor extends EmptyInterceptor {
@Override
public boolean onSave(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types) {
if (entity instanceof Auditable) {
int index = findPropertyIndex(propertyNames, "createdDate");
if (index != -1) {
state[index] = new Date(); // Setting the created date
}
index = findPropertyIndex(propertyNames, "createdBy");
if (index != -1) {
state[index] = "system"; // Setting the created by user
}
}
return false;
}
@Override
public boolean onFlushDirty(Object entity, Serializable id, Object[] currentState, Object[] previousState,
String[] propertyNames, Type[] types) {
if (entity instanceof Auditable) {
int index = findPropertyIndex(propertyNames, "modifiedDate");
if (index != -1) {
currentState[index] = new Date(); // Setting the modified date
}
index = findPropertyIndex(propertyNames, "modifiedBy");
if (index != -1) {
currentState[index] = "system"; // Setting the modified by user
}
}
return false;
}
private int findPropertyIndex(String[] propertyNames, String fieldName) {
for (int i = 0; i < propertyNames.length; i++) {
if (propertyNames[i].equals(fieldName)) {
return i;
}
}
return -1;
}
}
Explanation:
AuditInterceptorextendsEmptyInterceptorand overrides theonSaveandonFlushDirtymethods to track changes.onSave: This method sets the createdDate and createdBy when an entity is first saved.onFlushDirty: This method sets the modifiedDate and modifiedBy whenever an entity is updated.Auditableinterface can be used to mark entities that need auditing.
Configure Interceptor in Hibernate:
You can configure the interceptor in the Hibernate configuration file:
<hibernate-configuration>
<session-factory>
<!-- Configure Interceptor -->
<property name="hibernate.ejb.interceptor">com.example.interceptor.AuditInterceptor</property>
</session-factory>
</hibernate-configuration>
2. Hibernate Listeners
Hibernate Listeners হল আরেকটি powerful mechanism যা Hibernate entity lifecycle events এর সময় কার্যকর হয়। Hibernate Listeners সাধারণত @EntityListeners অ্যানোটেশন ব্যবহার করে entity এর উপর কাজ করে। এর মাধ্যমে আপনি entity state changes (e.g., on insert, update, delete) এর আগে বা পরে কোনো কার্যকলাপ করতে পারেন, যেমন auditing।
Listeners এর কাজ করার উপায়:
- @PrePersist: Entity persistence এর আগে কল হয় (insert হওয়ার আগে)।
- @PreUpdate: Entity update এর আগে কল হয়।
- @PreRemove: Entity remove হওয়ার আগে কল হয়।
Listener Example:
import javax.persistence.*;
import java.util.Date;
@Entity
@EntityListeners(AuditListener.class)
public class Employee implements Auditable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String name;
private String department;
private Date createdDate;
private String createdBy;
private Date modifiedDate;
private String modifiedBy;
// Getters and Setters
@Override
public Date getCreatedDate() {
return createdDate;
}
@Override
public void setCreatedDate(Date createdDate) {
this.createdDate = createdDate;
}
@Override
public String getCreatedBy() {
return createdBy;
}
@Override
public void setCreatedBy(String createdBy) {
this.createdBy = createdBy;
}
@Override
public Date getModifiedDate() {
return modifiedDate;
}
@Override
public void setModifiedDate(Date modifiedDate) {
this.modifiedDate = modifiedDate;
}
@Override
public String getModifiedBy() {
return modifiedBy;
}
@Override
public void setModifiedBy(String modifiedBy) {
this.modifiedBy = modifiedBy;
}
}
AuditListener Example:
import javax.persistence.PrePersist;
import javax.persistence.PreUpdate;
import java.util.Date;
public class AuditListener {
@PrePersist
public void setAuditFieldsOnCreate(Object entity) {
if (entity instanceof Auditable) {
Auditable auditable = (Auditable) entity;
auditable.setCreatedDate(new Date());
auditable.setCreatedBy("system");
}
}
@PreUpdate
public void setAuditFieldsOnUpdate(Object entity) {
if (entity instanceof Auditable) {
Auditable auditable = (Auditable) entity;
auditable.setModifiedDate(new Date());
auditable.setModifiedBy("system");
}
}
}
Explanation:
@EntityListeners(AuditListener.class): This annotation is used to associate theAuditListenerclass with theEmployeeentity.AuditListener: This listener class defines methods annotated with@PrePersistand@PreUpdateto set audit fields (createdDate,createdBy,modifiedDate,modifiedBy) whenever the entity is persisted or updated.- Auditable Interface: The
Auditableinterface is used to ensure that entities implement methods to get and set the auditing fields.
3. Auditing with Interceptors and Listeners Comparison
| Feature | Interceptors | Listeners |
|---|---|---|
| Activation | Activated globally in the Hibernate configuration file or programmatically | Activated by annotating the entity class with @EntityListeners |
| Use case | Better for centralized auditing logic for multiple entities | Useful for entity-specific logic and lifecycle events |
| Granularity | Works across all entities unless filtered by custom logic | Works at the entity level, specific to the annotated entity |
| Callback Methods | onSave, onFlushDirty, onDelete | @PrePersist, @PreUpdate, @PreRemove |
| Use with POJOs | Works well when you want to intercept session actions | Works directly with entity lifecycle events |
| Ideal for | General-purpose auditing, logging, or automatic actions | Entity-specific lifecycle actions such as auditing or validation |
- Hibernate Interceptors এবং Listeners দুটি powerful tools যা entity lifecycle events ট্র্যাক করার জন্য ব্যবহার করা হয়। এগুলির মাধ্যমে আপনি auditing তথ্য যেমন created date, modified date, created by, modified by ইত্যাদি সংগ্রহ করতে পারেন।
- Interceptors ব্যবহার করলে আপনি global level এ auditing করতে পারেন, যেখানে Listeners ব্যবহার করলে আপনি entity-specific auditing কার্যকর করতে পারেন।
- Auditing Hibernate এর মাধ্যমে ডেটাবেসে পরিবর্তন ট্র্যাক করার একটি সাধারণ কৌশল যা data integrity, change tracking, এবং audit trail নিশ্চিত করে।
Hibernate এর Interceptors এবং Listeners ব্যবহার করে auditing তথ্য সংগ্রহ করে আপনার অ্যাপ্লিকেশন আরও robust এবং maintainable করা যায়।
Read more